package com.inspinia.base.web.simple.config;

import com.inspinia.base.common.config.Swagger2Config;
import com.inspinia.base.web.simple.libs.freemarker.MyFreeMarkerView;
import com.jagregory.shiro.freemarker.ShiroTags;
import freemarker.template.utility.XmlEscape;
import org.springframework.context.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import java.nio.charset.Charset;
import java.util.*;

/**
 * springmvc javaconfig
 */

@Order(1)
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = {"com.inspinia.**.controller"},
        includeFilters ={
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class),
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = ControllerAdvice.class),
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)} )
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/public/**").addResourceLocations("/public/");
        registry.addResourceHandler("/pages/**").addResourceLocations("/WEB-INF/pages/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
    }

    @Bean
    public AnnotationDrivenBeanDefinitionParser annotationDrivenBeanDefinitionParser(){
        return new AnnotationDrivenBeanDefinitionParser();
    }

    @Bean(name = "mappingJacksonHttpMessageConverter")
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        converter.setSupportedMediaTypes(supportedMediaTypes);
        return converter;
    }


    @Bean(name = "swagger2Config")
    public Swagger2Config swaggerConfig(){
        return new Swagger2Config();
    }

    @Bean(name = "freemarkerConfig")
    public FreeMarkerConfig freeMarkerConfigurer(){
        FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
        freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/pages/");
        freeMarkerConfigurer.setDefaultEncoding("utf-8");
        freeMarkerConfigurer.setPreferFileSystemAccess(false);
        freeMarkerConfigurer.setFreemarkerSettings(freemarkerSettings());
        freeMarkerConfigurer.setFreemarkerVariables(setFreemarkerVariables());
        return freeMarkerConfigurer;
    }

    private Properties freemarkerSettings(){
        Properties properties = new Properties();
        properties.setProperty("template_update_delay","0");
        properties.setProperty("classic_compatible","true");
        properties.setProperty("locale","zh_CN");
        properties.setProperty("datetime_format","yyyy-MM-dd HH:mm:ss");
        properties.setProperty("date_format","yyyy-MM-dd");
        properties.setProperty("number_format","#.##");
        return properties;
    }

    public Map<String, Object> setFreemarkerVariables(){
        Map<String,Object> variablesMap = new HashMap<>(2);
        variablesMap.put("XmlEscape",xmlEscape());
        variablesMap.put("shiro",shiroTags());
        return variablesMap;
    }

    /**
     * 视图
     */
    @Bean(name = "viewResolver")
    public FreeMarkerViewResolver viewResolver(){
        FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
        viewResolver.setSuffix(".html");
        viewResolver.setExposeSpringMacroHelpers(true);
        viewResolver.setContentType("text/html;charset=UTF-8");
        viewResolver.setRequestContextAttribute("request");
        viewResolver.setViewClass(MyFreeMarkerView.class);
        return viewResolver;
    }

    /**
     * 配置静态资源处理
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    /**
     * 文件上传解析器
     */
    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver multipartResolver(){
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(524288000);
        multipartResolver.setDefaultEncoding("utf-8");
        return multipartResolver;
    }

    @Bean(name = "fmXmlEscape")
    public XmlEscape xmlEscape(){
        return new XmlEscape();
    }

    @Bean(name = "shiroTags")
    public ShiroTags shiroTags(){
        return new ShiroTags();
    }
}
